package cn.topevery.garden.dal.dao.impl;

import cn.topevery.garden.dal.dao.DiseaseDao;
import cn.topevery.garden.dal.dao.DiseaseFileDao;
import cn.topevery.garden.entity.po.Disease;
import cn.topevery.garden.entity.query.DiseaseQuery;
import cn.topevery.garden.entity.vo.DiseaseVO;
import cn.topevery.garden.framework.base.BaseDaoImpl;
import hw.topevery.basis.entity.po.SysUser;
import hw.topevery.basis.runtime.UserRuntime;
import hw.topevery.framework.db.CommandType;
import hw.topevery.framework.db.entity.DataPager;
import hw.topevery.framework.db.entity.SqlQueryMate;
import hw.topevery.framework.db.entity.SqlUpdateMate;
import hw.topevery.framework.db.enums.ScriptConditionEnum;
import hw.topevery.framework.entity.DbCsp;
import hw.topevery.framework.entity.KeyValue;
import hw.topevery.framework.entity.Value;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 病虫害表
 *
 * @author code-generate
 * @date 2022-01-05
 */
@Repository
public class DiseaseDaoImpl extends BaseDaoImpl<Disease> implements DiseaseDao {

    @Autowired
    DiseaseFileDao diseaseFileDao;

    @Override
    public <P extends DbCsp> List<Disease> getSearch(P para) {
        return null;
    }


    @Override
    public DataPager<DiseaseVO> listPage(DiseaseQuery query) {
        String table = "t_disease td";

        String columns = "td.*";

        int pageIndex = query.pageIndex - 1;
        int pageSize = query.pageSize;

        SqlQueryMate sqlQueryMate = new SqlQueryMate(table).setColumns(columns).setOrderBy("td.c_id desc");
        sqlQueryMate
                .where(true, "td.c_db_status", ScriptConditionEnum.Eq, 0)
        ;

        return getDataPager(sqlQueryMate, pageSize, pageIndex, DiseaseVO.class);
    }

    @Override
    public Disease getEntityByColumn(String key,String value){
        KeyValue<String> map=new KeyValue<>();
        map.key=key;
        map.value=value;
        return getEntityByColumnEqValue(map);
    }

    @Override
    public DataPager<DiseaseVO> getList(DiseaseQuery query) {
        String table = "t_disease td " +
                "join t_disease_month tdm on td.c_id = tdm.c_disease_id";
        String columns = "td.c_id,\n" +
                "        td.c_type,\n" +
                "        td.c_name,\n" +
                "        td.c_desc,\n" +
                "        td.c_pathogeny,\n" +
                "        td.c_law,\n" +
                "        td.c_cure,\n" +
                "        td.c_obj_name,\n" +
                "        td.c_remark,\n" +
                "        GROUP_CONCAT( tdm.c_month ORDER BY tdm.c_month SEPARATOR ',' ) AS c_month";
        String groupBy = "td.c_id,\n" +
                "            td.c_type,\n" +
                "            td.c_name,\n" +
                "            td.c_desc,\n" +
                "            td.c_pathogeny,\n" +
                "            td.c_law,\n" +
                "            td.c_cure,\n" +
                "            td.c_obj_name,\n" +
                "            td.c_remark";
        int pageIndex = query.pageIndex - 1;
        int pageSize = query.pageSize;
        SqlQueryMate sqlQueryMate = new SqlQueryMate(table).setColumns(columns);
        sqlQueryMate
                .where(true, "td.c_db_status", ScriptConditionEnum.Eq, 0)
                .where(true, "tdm.c_db_status", ScriptConditionEnum.Eq, 0)
                .where(StringUtils.isNotEmpty(query.getBeginDate()) && StringUtils.isNotEmpty(query.getBeginDate()), "c_db_create_date", ScriptConditionEnum.GreaterThanEq, query.getBeginDate())
                .where(StringUtils.isNotEmpty(query.getBeginDate()) && StringUtils.isNotEmpty(query.getEndDate()), "c_db_create_date", ScriptConditionEnum.LessThanEq, query.getBeginDate());
        sqlQueryMate.setGroupBy(groupBy);
        return getDataPager(sqlQueryMate, pageSize, pageIndex, DiseaseVO.class);
    }

    @Override
    public void update(Disease disease, Integer userId) {
        SysUser user = UserRuntime.getSysUser();
        update(user.userId, disease);
        String table = "t_disease_month tdm";
        SqlUpdateMate sqlUpdateMate = new SqlUpdateMate(table);
        sqlUpdateMate.setColumnValue(true, "c_db_status", 1);
        sqlUpdateMate.where(true, "c_disease_id", ScriptConditionEnum.Eq, disease.getId());
        run(sqlUpdateMate.getSql(), CommandType.Text, dbCommand -> {
            sqlUpdateMate.getParameters().forEach(dbCommand::addParameter);
            dbCommand.executeNonQuery();
        });
        diseaseFileDao.deleteByMainId(disease.getId(), userId);
        if (disease.getFileList() != null && !disease.getFileList().isEmpty()) {
            diseaseFileDao.insertList(disease.getFileList().stream().peek(temp -> {
                temp.setDataType(1);
                temp.setCreateTime(LocalDateTime.now());
                temp.setCreateId(user.userId);
                temp.setMainId(disease.getId());
                temp.setDbStatus(false);
                temp.setDbUpdateDate(LocalDateTime.now());
                temp.setDbUpdateId(userId);
            }).collect(Collectors.toList()));
        }
    }

    @Override
    public void insert(Disease disease, Integer userId) {
        SysUser user = UserRuntime.getSysUser();
        insert(user.userId, disease);
        if (disease.getFileList() != null && !disease.getFileList().isEmpty()) {
            diseaseFileDao.insertList(disease.getFileList().stream().peek(temp -> {
                temp.setDataType(1);
                temp.setCreateTime(LocalDateTime.now());
                temp.setCreateId(user.userId);
                temp.setMainId(disease.getId());
                temp.setDbStatus(false);
                temp.setDbUpdateDate(LocalDateTime.now());
                temp.setDbUpdateId(userId);
            }).collect(Collectors.toList()));
        }
    }

    @Override
    public void deleteByIds(List<String> ids, List<String> months) {
        String table = "t_disease_month tdm,t_disease td";
        SqlUpdateMate sqlUpdateMate = new SqlUpdateMate(table);
        sqlUpdateMate.setColumnValue(true, "tdm.c_db_status", 1)
                .setColumnValue(true, "td.c_db_status", 1);
        sqlUpdateMate.where(CollectionUtils.isNotEmpty(ids), "tdm.c_disease_id", ScriptConditionEnum.In, ids)
                .where(CollectionUtils.isNotEmpty(ids), "td.c_id", ScriptConditionEnum.In, ids)
                .where(CollectionUtils.isNotEmpty(months), "tdm.c_month", ScriptConditionEnum.In, months);
        run(sqlUpdateMate.getSql(), CommandType.Text, dbCommand -> {
            sqlUpdateMate.getParameters().forEach(dbCommand::addParameter);
            dbCommand.executeNonQuery();
        });
    }

    @Override
    public Disease getByIdAndMonth(Integer id) {
        Value<Disease> result = new Value<>();
        String columns = "td.c_id id,\n" +
                "\ttd.c_type type,\n" +
                "\ttd.c_name name,\n" +
                "\ttd.c_desc desc,\n" +
                "\ttd.c_pathogeny pathogeny,\n" +
                "\ttd.c_law law,\n" +
                "\ttd.c_cure cure,\n" +
                "\ttd.c_obj_name objName,\n" +
                "\ttd.c_remark remark,\n" +
                "\tGROUP_CONCAT( tdm.c_month ORDER BY tdm.c_month SEPARATOR ',' ) AS months";
        String table = "t_disease td join t_disease_month " +
                "on tdm td.c_id = tdm.c_disease_id";
        String groupBy = "td.c_id,\n" +
                "\ttd.c_type,\n" +
                "\ttd.c_name,\n" +
                "\ttd.c_desc,\n" +
                "\ttd.c_pathogeny,\n" +
                "\ttd.c_law,\n" +
                "\ttd.c_cure,\n" +
                "\ttd.c_obj_name,\n" +
                "\ttd.c_remark";
        SqlQueryMate sqlQueryMate = new SqlQueryMate(table).setColumns(columns);
        sqlQueryMate.where(true, "td.c_db_status", ScriptConditionEnum.Eq, 0)
                .where(id != null, "td.c_id", ScriptConditionEnum.Eq, id)
                .where(id != null, "td.c_id", ScriptConditionEnum.Eq, id)
                .where(true,"tdm.c_db_status", ScriptConditionEnum.Eq, 0);
        sqlQueryMate.setGroupBy(groupBy);
        run(sqlQueryMate.getSql(), CommandType.Text, dbCmd -> {
            result.data = dbCmd.executeToEntity(Disease.class);
        });
        return result.data;
    }
}
